/*
 *  surface.cpp
 *  EPPI-0.0
 *
 *  Created by Juan Carlos García Orden on 06/04/11
 *
 */

#include "surface.h"

//**
Surface::Surface():
name(""),
contactAllOption(false),
contactFileOption(false)
{}

//**
Surface::Surface(const string& n,
				 vector<vector<double> >& vlp,
				 vector<vector<int> >& vle):
name(n),
vLocalPoints(vlp),
vLocalElements(vle)
{
	nLocalPoints = vLocalPoints.size();
	nLocalElements = vLocalElements.size();
	
	contactAllOption = false;
	contactFileOption = false;

	S = 0;	
	dS.setZero();
	ddS.setZero();	
}

// ***
Surface::~Surface()
{}

// ***
Surface::Surface(const string& n):
name(n)
{
	contactAllOption = false;
	contactFileOption = false;

	S = 0;
	dS.setZero();
	ddS.setZero();
}

// ***
void Surface::createContactPoints(void)
{	
	// If nothing is said about contact, take by default the "all" option
	if (contactAllOption == false && contactFileOption == false)
		contactAllOption = true;
	
	// All nodes are for contact, and no more are added
	if (contactAllOption == true)
	{
		vContactPoints = vLocalPoints;
	}
	
	if (contactFileOption == true)
	{

		string line;
		vector<string> linesFile;
		
		vector<double> vauxd(3);
		double auxd;
		int nnode;
		
		inContact.open(contactFileName.c_str());
		
		while (inContact.good())
		{
			getline(inContact, line);
			linesFile.push_back(line);
		}
		
		if (!linesFile[0].compare("NODES"))
		{
			for (int i = 1; i < linesFile.size(); ++i)
			{
				istringstream iss(linesFile[i], istringstream::in);
				
				iss >> nnode;
				vContactPoints.push_back(vLocalPoints[nnode]);
			}
		}

		if (!linesFile[0].compare("COORD"))
		{
			for (int i = 1; i < linesFile.size(); ++i)
			{
				istringstream iss(linesFile[i], istringstream::in);
				
				for (int j = 0; j < 3; ++j)
				{
					iss >> vauxd[j];
				}
				vContactPoints.push_back(vauxd);
			}			
		}		
		inContact.close();
	}
	
	cout << "Total Contact Points: " << vContactPoints.size() << endl;
}

// ***
void Surface::writeVTU(vector<double>& cmm, vector<vector<double> >& R, ofstream& localFGraph)
{	
	int i;
	int j;
	
	vector<double> vPosGlobal(3);
	
	localFGraph << "<?xml version=\"1.0\"?>\n";
	localFGraph << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
	localFGraph << "\t<UnstructuredGrid>\n";
	localFGraph << "\t\t<Piece NumberOfPoints=\"" << nLocalPoints << "\" NumberOfCells=\"" << nLocalElements << "\">\n";
	localFGraph << "\t\t\t<Points>\n";
	localFGraph << "\t\t\t\t<DataArray type=\"Float64\" NumberOfComponents=\"3\" format=\"ascii\">";
	
	for (i = 0; i < nLocalPoints; ++i)
	{
		localFGraph << "\n";
		localFGraph << "\t\t\t\t\t";
		
		rigidTrans(vLocalPoints[i], cmm, R, vPosGlobal);
		
		for (j = 0; j < vLocalPoints[i].size(); ++j)
		{
			localFGraph << vPosGlobal[j] << "\t";
		}
	}
	
	localFGraph << "\n";
	localFGraph << "\t\t\t\t</DataArray>\n";
	localFGraph << "\t\t\t</Points>\n";
	localFGraph << "\t\t\t<Cells>\n";
	localFGraph << "\t\t\t\t<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">";
	
	for (i = 0; i < nLocalElements; ++i)
	{
		localFGraph << "\n";
		localFGraph << "\t\t\t\t\t";
		
		for (j = 0; j < vLocalElements[i].size(); ++j)
		{
			localFGraph << vLocalElements[i][j] << "\t";
		}
	}
	localFGraph << "\n";
	localFGraph << "\t\t\t\t</DataArray>\n";
	localFGraph << "\t\t\t\t<DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">";
	localFGraph << "\n";
	localFGraph << "\t\t\t\t\t";
	
	for (i = 0; i < nLocalElements; ++i)
	{
		localFGraph << vLocalElements[0].size() * (1 + i) << "\t";
	}
	
	localFGraph << "\n";
	localFGraph << "\t\t\t\t</DataArray>\n";
	localFGraph << "\t\t\t\t<DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">";
	localFGraph << "\n";
	localFGraph << "\t\t\t\t\t";
	
	for (i = 0; i < nLocalElements; ++i)
	{
		if (vLocalElements[0].size() == 4)
		{
			localFGraph << 9 << "\t";
		}
		else if (vLocalElements[0].size() == 3)
		{
			localFGraph << 5 << "\t";
		}
	}
	
	localFGraph << "\n";
	localFGraph << "\t\t\t\t</DataArray>\n";
	localFGraph << "\t\t\t</Cells>\n";
	
	/*
	//-- Begin PointData --//
	localFGraph << "\t\t\t<PointData ";
	localFGraph << "Scalars=\"Temperature\">\n";
	localFGraph << "Vectors=\"Velocity\">\n";

	//--DataArray: Scalars	
	localFGraph << "\t\t\t\t<DataArray ";
	localFGraph << "type=\"Float32\" ";
	localFGraph << "Name=\"Temperature\" ";
	localFGraph << "format=\"ascii\">\n";

	for (i = 0; i < nLocalPoints; ++i)
	{
		localFGraph << "\t\t\t\t\t";
		localFGraph << "0" << "\n";
	}	
	localFGraph << "\t\t\t\t</DataArray>\n";
	//--DataArray: Scalars
	
	//--DataArray: Vectors
	localFGraph << "\t\t\t\t<DataArray ";
	localFGraph << "type=\"Float64\" ";
	localFGraph << "Name=\"Velocity\" ";	
	localFGraph << "NumberOfComponents=\"3\" ";
	localFGraph << "format=\"ascii\">";
	
	Eigen:: Vector3d vnormal;
	
	for (i = 0; i < nLocalPoints; ++i)
	{
		localFGraph << "\n";
		localFGraph << "\t\t\t\t\t";
		
		vnormal =  evaldS(vLocalPoints[i][0],
						  vLocalPoints[i][1],
						  vLocalPoints[i][2]);
			
//		localFGraph << vnormal.x() << "\t";
//		localFGraph << vnormal.y() << "\t";
//		localFGraph << vnormal.z() << "\t";						

		localFGraph << 0. << "\t";
		localFGraph << 0. << "\t";
		localFGraph << 0. << "\t";								
	}
	
	localFGraph << "\n";
	localFGraph << "\t\t\t\t</DataArray>\n";	
	//--DataArray: Vectors
	
	localFGraph << "\t\t\t</PointData>\n";	
	//-- End PointData --//
	*/
	
	localFGraph << "\t\t</Piece>\n";
	localFGraph << "\t</UnstructuredGrid>\n";
	localFGraph << "</VTKFile>\n";
}

// ***
double Surface::sgn(double a)
{
	if (a < 0)
	{
		return -1.0;
	}
	if (a == 0)
	{
		return 0.0;
	}
	if (a > 0)
	{
		return 1.0;
	}	
}